#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
飞书lark长连接接口
Attributes:
    __version__ (str): "0.0.1"
    __copyright__ (str): "Copyright (C) 2025 z"
    __license__ (str): "MIT"
    __author__ (str): "Z"
"""

import re
import json
import requests

from wingman import logger
from wingman.common.error import ErrorCode
from config.system import FEISHU_APP_ID, FEISHU_APP_SECRET, IS_FEISHU_SEND, FLASK_ROBOT_WEBHOOK

import lark_oapi as lark
from lark_oapi.api.im.v1 import *


def remove_user_prefix(s):
    """使用正则表达式匹配以@_user_开头,后跟任意数字的字符串"""
    return re.sub(r'^@_user_\d+\s*', '', s)


def send_data_to_flask(data, allowed_origin=None):
    """消息回送 冗余钉钉消息格式"""
    json_data = { "text": {"content": f" {remove_user_prefix(data)}"} } #注意这里有个 @_user_1
    response_data = requests.post(FLASK_ROBOT_WEBHOOK, json=json_data, headers={'Content-Type': 'application/json'})
    response_data.raise_for_status()
    # 解析 Flask 返回的响应
    result = json.dumps({ "text": response_data.json()["result_msg"]})
    return result


# P2ImMessageReceiveV1 为接收消息 v2.0；CustomizedEvent 内的 message 为接收消息 v1.0。
def do_p2_im_message_receive_v1(data: lark.im.v1.P2ImMessageReceiveV1) -> None:
    """
    [Lark] [DEBUG]
    receive message,
    message_type: event,
    message_id: 6eb66028-f3bc-4882-9e8d-7b204b844527,
    trace_id: 1f3498987b888a7f5cc59a6d528c5ddc,
    payload: {
        "schema":"2.0",
        "header":{
            "event_id":"1f3498987b888a7f5cc59a6d528c5ddc",
            "token":"",
            "create_time":"1741157044281",
            "event_type":"im.message.receive_v1",
            "tenant_key":"11f844c41d80575e",
            "app_id":"cli_a49fb0639eb8100d"
        },
    "event":{
        "message":{
            "chat_id":"oc_e5ae0734b3b2de17d4df10aeec909546",
            "chat_type":"group",
            "content":"{\"text\":\"@_user_1 fdsa\"}",
            "create_time":"1741157043930",
            "mentions":[{
                "id":{
                    "open_id":"ou_76ff3c47cf9e6a50c9120ce67873dba8",
                    "union_id":"on_55d4df46e00d9b9596a3d6a3a4c321f2",
                    "user_id":null
                    },
                "key":"@_user_1","name":"test",
                "tenant_key":"11f844c41d80575e"
            }],
            "message_id":"om_4ea427cae5872166e836bd720e9a5823",
            "message_type":"text",
            "update_time":"1741157043930",
            "user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.86 Safari/537.36 Lark/7.32.11 LarkLocale/zh_CN ttnet SDK-Version/7.32.9"},
            "sender":{
                "sender_id":{
                    "open_id":"ou_aa0e26b99a6b7f24df1fd5d5accbc726",
                    "union_id":"on_67111589ee76e8eaa41ced73b450d4ce","user_id":null
                    },
            "sender_type":"user","tenant_key":"11f844c41d80575e"
            }
        }
    }
    [conn_id=7478211706928758788]
    """

    # 判断是否为文件消息
    if data.event.message.message_type == "text":
        # 获取消息内容和提及信息
        message_content = data.event.message.content
        # 解析消息内容
        message_text = json.loads(message_content).get("text", "")
    else:
        message_text = "解析消息失败,请发送文本消息\nparse message failed, please send text message"

    content = send_data_to_flask(message_text)
    mentions = data.event.message.mentions

    # 检查是否提及了应用
    if isinstance(mentions, list):
        is_mentioned = any(mention.id.open_id == "ou_76ff3c47cf9e6a50c9120ce67873dba8" for mention in mentions)
    else:
        is_mentioned = False

    # 使用回复OpenAPI回复消息
    # https://open.larkoffice.com/document/server-docs/im-v1/message/reply
    # 判断是否为私聊,并回复
    if data.event.message.chat_type == "p2p":
        request = (
            CreateMessageRequest.builder()
            .receive_id_type("chat_id")
            .request_body(
                CreateMessageRequestBody.builder()
                .receive_id(data.event.message.chat_id)
                .msg_type("text")
                .content(content)
                .build()
            )
            .build()
        )
        response = client.im.v1.chat.create(request)
        if not response.success():
            raise Exception(f"client.im.v1.chat.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}")
    # 群内@和正常发消息都为 data.event.message.chat_type == "group"
    # 如果@了应用,回复消息
    elif is_mentioned:
        request: ReplyMessageRequest = (
            ReplyMessageRequest.builder()
            .message_id(data.event.message.message_id)
            .request_body(
                ReplyMessageRequestBody.builder()
                .content(content)
                .msg_type("text")
                .build()
            )
            .build()
        )
        response: ReplyMessageResponse = client.im.v1.message.reply(request)
        if not response.success():
            raise Exception(f"client.im.v1.chat.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}")
    # 响应群内消息
    else:
        pass
    #     request: ReplyMessageRequest = (
    #         ReplyMessageRequest.builder()
    #         .message_id(data.event.message.message_id)
    #         .request_body(
    #             ReplyMessageRequestBody.builder()
    #             .content(content)
    #             .msg_type("text")
    #             .build()
    #        )
    #         .build()
    #    )
    #     response: ReplyMessageResponse = client.im.v1.message.reply(request)
    #     if not response.success():
    #         raise Exception(f"client.im.v1.message.reply failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}")


def do_p2_im_chat_access_event(data: lark.im.v1.P2ImChatAccessEventBotP2pChatEnteredV1) -> None:
    logger.warning(ErrorCode.LARK_EVENT.value, "do_p2_im_chat_access_event", __name__)


def do_p2_im_chat_disbanded_v1(data: lark.im.v1.P2ImChatDisbandedV1) -> None:
    logger.warning(ErrorCode.LARK_EVENT.value, "do_p2_im_chat_disbanded_v1", __name__)


def do_customized_event(data: lark.CustomizedEvent) -> None:
    logger.warning(ErrorCode.LARK_EVENT.value, "do_customized_event", __name__)

"""register_p1 对应 v1.0 版本,
参数值需要传入事件类型。例如 message（历史版本 接收消息v1.0 事件）
P2 表示事件版本为 v2.0,ImMessageReceiveV1 对应事件类型 im.message.receive_v1。  data: lark.im.v2.P2ImChatEnteredV1
"""

event_handler = lark.EventDispatcherHandler.builder("", "") \
    .register_p2_im_message_receive_v1(do_p2_im_message_receive_v1) \
    .register_p2_im_chat_access_event_bot_p2p_chat_entered_v1(do_p2_im_chat_access_event) \
    .register_p2_im_chat_disbanded_v1(do_p2_im_chat_disbanded_v1) \
    .register_p1_customized_event("message", do_customized_event) \
    .build()

# 创建 LarkClient 对象,用于请求OpenAPI, 并创建 LarkWSClient 对象,用于使用长连接接收事件。
client = lark.Client.builder().app_id(f"{FEISHU_APP_ID}").app_secret(f"{FEISHU_APP_SECRET}").build()
wsClient = lark.ws.Client(f"{FEISHU_APP_ID}", f"{FEISHU_APP_SECRET}", event_handler=event_handler, log_level=lark.LogLevel.DEBUG,)


def main():
    if IS_FEISHU_SEND:
        try:
            wsClient.start()
        except KeyboardInterrupt:
            logger.warning(ErrorCode.LARK_OUT.value, "lark退出...", __name__)


if __name__ == "__main__":
    main()
